import {
  type Ref,
  shallowRef,
  unref,
  onMounted,
  onDeactivated,
  onBeforeUnmount,
  nextTick,
  watch
} from 'vue'

import echarts from './config'

export type EChartsCoreOption = echarts.EChartsCoreOption

interface EchartsOption extends echarts.EChartsInitOpts {
  theme: Ref<string | Object>
}
const useEcharts = (elRef: Ref<HTMLDivElement>, options: EchartsOption) => {
  const charts = shallowRef<echarts.ECharts>()
  // 从options里获取除theme外的其他配置
  // 复制 options 对象并剔除 theme 字段
  let { theme, ...initOptions } = options
  let chartOptions = null
  // 初始化
  const initCharts = () => {
    const el = unref(elRef)
    if (!el || !unref(el)) {
      return
    }
    charts.value = echarts.init(el, theme.value, initOptions)
  }

  const setOptions = (options: EChartsCoreOption) => {
    nextTick(() => {
      options.backgroundColor = 'transparent'
      chartOptions = options
      charts.value && charts.value.setOption(options)
    })
  }

  // 监听 theme.value 的变化
  watch(
    () => theme.value,
    () => {
      charts.value.dispose()
      charts.value = null
      initCharts() // 重新初始化图表
      setOptions(chartOptions)
    }
  )

  // 重新窗口变化时，重新计算
  const resize = () => {
    charts.value && charts.value.resize()
  }

  /**
   * 清除图表
   *
   * @description 如果实例存在，则销毁实例并移除窗口大小改变事件监听器
   */
  const clearChart = () => {
    window.removeEventListener('resize', resize)
    if (charts.value) {
      charts.value.dispose()
      charts.value = null
    }
    chartOptions = null
    theme = null
    initOptions = null
  }

  onMounted(() => {
    initCharts()
    window.addEventListener('resize', resize)
  })

  // 页面keepAlive时，不监听页面
  onDeactivated(() => {
    clearChart()
  })

  onBeforeUnmount(() => {
    clearChart()
  })

  return {
    charts,
    initCharts,
    setOptions,
    resize,
    clearChart
  }
}

export { useEcharts }
